package com.open.capacity.paper.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.model.PaperQuestion;
import com.open.capacity.common.model.Question;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.paper.dao.PaperQuestionDao;
import com.open.capacity.paper.dao.QuestionDao;
import com.open.capacity.paper.service.QuestionService;
import com.open.capacity.paper.vo.QuestionExcelVo;
import com.open.capacity.paper.vo.QuestionVo;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liangd
 * @since 2021-02-02 15:16
 */
@Service
@Slf4j
public class QuestionServiceImpl extends ServiceImpl<QuestionDao, Question> implements QuestionService {

    @Autowired
    private QuestionDao questionDao;

    @Autowired
    private PaperQuestionDao paperQuestionDao;

    @Override
    public PageResult<Question> getQuestions(Map<String, Object> params) throws ServiceException {
        try {
            if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null) {
                PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);
            }
            List<Question> list = questionDao.findList(params);
            PageInfo<Question> pageInfo = new PageInfo<>(list);
            return PageResult.<Question>builder().code(0).count(pageInfo.getTotal()).data(pageInfo.getList()).build();
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateQuestion(Question question) throws ServiceException {
        try {
            question.setUpdtim(new Date());
            questionDao.updateById(question);
            return Result.succeed("更新成功");
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveQuestion(Question question) throws ServiceException {
        try {
            question.setCretim(new Date());
            question.setStatus(1);
            questionDao.insert(question);
            return Result.succeed("添加成功");
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteQuestion(Integer quesid) throws ServiceException {
        try {
            List<PaperQuestion> list = new LambdaQueryChainWrapper<>(paperQuestionDao).eq(PaperQuestion::getQuesid, quesid).list();
            if (list.size() > 0) {
                return Result.failed("该问题与问卷已关联，请先移除关系，在进行操作！");
            }
            Question question = questionDao.selectById(quesid);
            question.setStatus(2);
            questionDao.updateById(question);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public Result getAllQuestions(Integer papeid) throws ServiceException {
        try {
            List<Map<String, Object>> questionTrees = new ArrayList<>();
            Set<Integer> papeids = new HashSet<>();
            papeids.add(papeid);
            //查询当前问题已有选项
            Set<Question> paperQuestions = questionDao.findQuestionByPaperIds(papeids);
            List<Question> allQuestions = questionDao.findList(null);
            Map<Integer, Question> collect = paperQuestions.stream().collect(Collectors.toMap(Question::getQuesid, Question -> Question));
            for (Question question : allQuestions) {
                Map<String, Object> questionTree = new HashMap<>();
                questionTree.put("id", question.getQuesid());
                questionTree.put("name", question.getQtitle());
                questionTree.put("open", true);
                questionTree.put("checked", false);
                if (collect.get(question.getQuesid()) != null) {
                    questionTree.put("checked", true);
                }
                questionTrees.add(questionTree);
            }
            return Result.succeed(questionTrees, "");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addQuestions(Integer papeid, Set<Integer> questIds) throws ServiceException {
        try {
            List<PaperQuestion> paperQuestions = new LambdaQueryChainWrapper<>(paperQuestionDao).eq(PaperQuestion::getPapeid, papeid).list();
            Set<Integer> collect = paperQuestions.stream().map(PaperQuestion::getQuesid).collect(Collectors.toSet());
            Collection<Integer> subtract = CollectionUtils.subtract(questIds, collect);
            Set<Integer> set = new HashSet<>(subtract);
            if (set.size() != 0) {
                List<PaperQuestion> paperQuestionList = new ArrayList<>();
                for (Integer in : set) {
                    PaperQuestion build = PaperQuestion.builder().papeid(papeid).quesid(in).build();
                    paperQuestionList.add(build);
                }
                paperQuestionDao.insertBatch(paperQuestionList);
            }
            Collection<Integer> subtract1 = CollectionUtils.subtract(collect, questIds);
            Set<Integer> set1 = new HashSet<>(subtract1);
            if (set1.size() != 0) {
                paperQuestionDao.deleteBatchByIds(papeid, set1);
            }
            return Result.succeed("操作成功");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public void exportQuestion(Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) throws ServiceException {
        try {
            List<Question> questionList = questionDao.findList(params);
            List<QuestionExcelVo> list = new ArrayList<>();
            for (Question question:questionList){
                QuestionExcelVo questionExcelVo = new QuestionExcelVo();
                BeanUtils.copyProperties(question,questionExcelVo);
                list.add(questionExcelVo);
            }
            UUID uuid = UUID.randomUUID();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=" + uuid + ".xls");
            @Cleanup OutputStream outputStream = null;
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("问题列表", "问题"), QuestionExcelVo.class, list);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

}
